# -*- coding: utf-8 -*-

import re
import dns.resolver
import time
import datetime
import threading
import queue
import sys

from WSCounter import WSCounter

class DnsValidator:
	dns = ''
	
	def __init__(self, dns):
		self.dns = dns
	
	def validate(self, names, ip):
		print("Start validate in " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
		
		result = {'valids': [], 'errors': [], 'invalids': []}
		
		namesQueue = queue.Queue()
		for name in names:
			namesQueue.put(name)
		
		vCounter = WSCounter(25, 250)
		for i in range(5):
			worker = DnsValidatorThread(self.dns, namesQueue, ip, result, vCounter)
			worker.daemon = True
			worker.start()
		namesQueue.join()
		
		print("\nValidation ended in " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
		
		return result

class DnsValidatorThread(threading.Thread):
	def __init__(self, dns, namesQueue, ip, result, counter):
		super().__init__()
		self.dns = dns
		self.result = result
		self.namesQueue = namesQueue
		self.ip = ip
		self.counter = counter
	
	def run(self):
		nsRespRe = re.compile(r";ANSWER\s(?P<data>(.|\s)*)\s;AUTHORITY", re.M)
		ipRe = re.compile(r"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})")
		
		while True:
			try:
				name = self.namesQueue.get()
				
				self.counter.up()
					
				query = dns.message.make_query(name, 'A');
				try:
					result   = dns.query.tcp(query, self.dns, timeout=2)
					response = nsRespRe.search(result.to_text())	
					if response is not None:
						for addr in ipRe.findall(response.group('data')):
							if addr == self.ip:
								self.result['valids'].append(name)
							else:
								self.result['invalids'].append(name)
				except Exception:
					self.result['errors'].append(name)
					time.sleep(3)
			finally:
				self.namesQueue.task_done()		